#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>

/* author: panda_zhangs
 * date: 6/17/2022
 * desc: 通过多线程互斥锁模拟多窗口售货
 */

// 定义一个工厂结构体；
struct factory
{
    int curNums;
    char *name;
};
// 声明一个互斥量作为锁对象；
pthread_mutex_t mutex;
const int THREAD_NUM=4;
int resno;
// 生成货物编号信息

// 未加锁的货物销售执行任务
void * sellGood(void *arg){
    struct factory* fctr = (struct factory*)arg;
    int oldval=0;
    while(fctr->curNums>1){
    --fctr->curNums;
    oldval = fctr->curNums;
    char tickno[30];
    sprintf(tickno,"%s-%d",fctr->name,fctr->curNums);
    printf("id:%ld 出售%-10s;\n",pthread_self(),tickno);
    sleep(1);
    }
    if(fctr->curNums<=0){
        resno=-1;
        pthread_exit((void*)&resno);
    }else{
        resno=oldval;
        pthread_exit((void*)&resno);
    }
}

// 带有互斥锁的货物销售程序
void * sellGoodWithLk(void *arg){
    struct factory* fctr = (struct factory*)arg;
    int oldval;
    while(fctr->curNums>1){
    pthread_mutex_lock(&mutex);
    if(fctr->curNums>1){
        --fctr->curNums;
        oldval = fctr->curNums;
        char tickno[30];
        sprintf(tickno,"%s-%d",fctr->name,fctr->curNums);
        printf("id:%ld 出售%10s;\n",pthread_self(),tickno);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }else{
        pthread_mutex_unlock(&mutex);
        break;
    }
    }
    if(fctr->curNums<=0){
        resno=-1;
        pthread_exit((void*)&resno);
    }else{
        resno=oldval;
        pthread_exit((void*)&resno);
    }   
}

// 工厂初始化程序
void initFactory(struct factory* fctr,int maxNum,const char * Fname){
    fctr->curNums = maxNum;
    fctr->name = (char*)malloc(sizeof(char)*(strlen(Fname)+1));
    memset(fctr->name,0,strlen(Fname)+1);
    strncpy(fctr->name,Fname,strlen(Fname)+1);
}
// 工厂销毁程序
void destoryFactory(struct factory* fctr){
    free(fctr->name);
    printf("暂时停工\n");
}


int main(){
    int nil=0;
    pthread_t thread[THREAD_NUM];
    struct factory fctr;
    int *ret[THREAD_NUM];
    printf("无锁方法执行情况：\n");
    initFactory(&fctr,20,"小米手机");
    for(int i=0;i<THREAD_NUM;++i){
        nil = pthread_create(&thread[i],NULL,sellGood,&fctr);
        if(nil){
            printf("pthread create error,[%s]\n",strerror(nil));
            destoryFactory(&fctr);
            return -1;
        }
    }
    
    for(int i=0;i<THREAD_NUM;++i){
        pthread_join(thread[i],(void**)&ret[i]);
        printf("线程 %d 的返回信号是 %d \n",i+1,*ret[i]);
    }
    destoryFactory(&fctr);

    printf("有锁方法执行\n");
    pthread_mutex_init(&mutex,NULL);

    initFactory(&fctr,20,"苹果手机");
    for(int i=0;i<THREAD_NUM;++i){
        nil = pthread_create(&thread[i],NULL,sellGoodWithLk,&fctr);
        if(nil){
            printf("pthread create error,[%s]\n",strerror(nil));
            destoryFactory(&fctr);
            pthread_mutex_destroy(&mutex);
            return -1;
        }
    }
    for(int i=0;i<THREAD_NUM;++i){
        pthread_join(thread[i],(void**)&ret[i]);
        printf("线程 %d 的最后售出序列号是 %d \n",i+1,*ret[i]);

    }
    pthread_mutex_destroy(&mutex);
    printf("方法执行结束\n");






}
